package com.cysyz.mylib.hibernatedao;


import com.cysyz.mylib.dao.engine.ClassMetadata;
import com.cysyz.mylib.dao.engine.PersistenceEngine;
import com.cysyz.mylib.dao.engine.Query;
import com.cysyz.mylib.dao.engine.SQLQuery;
import org.hibernate.SessionFactory;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.hql.QueryTranslator;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;

public class PersistenceEngineSpringHibernate extends HibernateDaoSupport implements PersistenceEngine {
	
	@Resource(name="sessionFactory")
	public void setSessionFactoryDi(SessionFactory sessionFactory) {
		this.setSessionFactory(sessionFactory);
	}
	public void persist(Object entity) {
		this.getHibernateTemplate().save(entity);
	}

	public void remove(Object entity) {
		this.getHibernateTemplate().delete(entity);
	}
	
	@SuppressWarnings("rawtypes")
	public void removeByCollection(List list) {
		this.getHibernateTemplate().deleteAll(list);
	}
	
	public void merge(Object entity) {
		this.getHibernateTemplate().update(entity);
	}

	public <T> T get(Class<T> entityClass, Serializable entityID) {
		
		return this.getHibernateTemplate().get(entityClass, entityID);
	}

	public <T> T getReference(Class<T> entityClass, Serializable entityID) {
		//SQLQuery createSQLQuery = this.getSession().createSQLQuery("");

		return this.getHibernateTemplate().load(entityClass, entityID);
	}
	
	public Query createQuery(String ql) {
		return new QueryHibernate(this.getHibernateTemplate().getSessionFactory().getCurrentSession().createQuery(ql));
	}
	
	@Override
	public SQLQuery createSQLQuery(String sql) {
		
		return new SQLQueryHibernate(this.getHibernateTemplate().getSessionFactory().getCurrentSession().createSQLQuery(sql));
	}

	@Override
	public SQLQuery TranslateToCountSQL(Query queryForData) {
		String sql = this.getSql(queryForData.getQueryString(), this.getSessionFactory());
		return this.createSQLQuery(sql);
	}

	@Override
	public SQLQuery TranslateToCountSQL(String hql) {
		String sql = this.getSql(hql, this.getSessionFactory());
		return this.createSQLQuery(sql);
	}

	@Override
	public ClassMetadata getClassMetadata(Class entityClass) {
		return new ClassMetadataHibernate(this.getSessionFactory().getClassMetadata(entityClass));
	}

	protected String getSql(String originalHql, org.hibernate.SessionFactory sessionFactory) {

		SessionFactoryImplementor factory = (SessionFactoryImplementor) sessionFactory;
		QueryTranslator queryTranslator = factory.getSettings().getQueryTranslatorFactory()
				.createQueryTranslator(originalHql, originalHql, Collections.EMPTY_MAP, factory);
		queryTranslator.compile( factory.getSettings().getQuerySubstitutions(), false );


        /*QueryTranslatorImpl queryTranslator = new QueryTranslatorImpl(originalHql, originalHql,
           Collections.EMPTY_MAP, (org.hibernate.engine.SessionFactoryImplementor)sessionFactory);

        queryTranslator.compile(Collections.EMPTY_MAP, false);*/

        return "select count(*) as c from (" + queryTranslator.getSQLString() + ") tmp_count_t";
	}

}
